package com.lz.sports.vm.group

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import com.jeremyliao.liveeventbus.LiveEventBus
import com.lz.library.base.BaseModel
import com.lz.library.base.BaseViewModel
import com.lz.library.base.SingleLiveData
import com.lz.sports.bean.DeviceGroup
import com.lz.sports.bean.DeviceInfo
import com.lz.sports.core.*
import com.lz.sports.db.DeviceDatabase
import com.lz.ub.UBCCallback
import com.lz.ub.UBCDevice
import com.lz.ub.UBCManager
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext

//设备组编辑
class DeviceGroupEditViewModel : BaseViewModel<BaseModel>(), UBCCallback {

    //设备组
    val deviceGroup = MutableLiveData<DeviceGroup>()
    //清空
    val clearEvent = SingleLiveData<Boolean>()
    //延时操作
    val delayEvent = SingleLiveData<Int>()

    override fun onCreate(owner: LifecycleOwner) {
        UBCManager.get().addUBCCallback(this)
        UBCManager.get().restart()
        delayEvent.setValue(2)
    }

    override fun onCleared() {
        super.onCleared()
        UBCManager.get().removeUBCCallback(this)
        UBCManager.get().cancelAndClearAuto()
    }

    fun bindDeviceInfo(deviceInfo: DeviceInfo): Boolean {
        val group = deviceGroup.value ?: return false
        if (group.id == deviceInfo.groupId) {
            group.bindDeviceInfo(deviceInfo)
            deviceGroup.value = group
        }
        return true
    }

    fun modifyName(name: String) {
        val group = deviceGroup.value ?: return
        launch {
            withContext(Dispatchers.Default) {
                DeviceDatabase.get().modifyDeviceGroupName(name, group.id)
            }
            group.name = name
            deviceGroup.value = group
            LiveEventBus.get("DeviceGroup_edit_name", DeviceGroup::class.java).post(group)
        }
    }

    fun connect() {
        val group = deviceGroup.value ?: return
        if (group.deviceList().isEmpty()) return
        launch {
            updateDialogLoading(true)
            withContext(Dispatchers.IO) {
                group.deviceList().forEach {
                    UBCManager.get().addDevice(it.mac, DEVICE_W_NUM, DEVICE_R_NUM, true)
                    Thread.sleep(10)
                }
                Thread.sleep(50)
                UBCManager.get().connect()
            }
            delay(2000)
            updateDialogLoading(false)
        }
    }

    //获取电量
    fun battery() {
        val group = deviceGroup.value ?: return
        if (group.deviceList().isEmpty()) return
        launch {
            updateDialogLoading(true)
            UBCManager.get().pushHexCommand(COMMAND_INFO)
            delay(1000)
            updateDialogLoading(false)
        }
    }

    //取消绑定设备
    fun unbind(deviceInfo: DeviceInfo): Boolean {
        val group = deviceGroup.value ?: return false
        if (group.unbindDeviceInfo(deviceInfo)) {
            launch {
                withContext(Dispatchers.Default) {
                    DeviceDatabase.get().unbindDeviceInfo(deviceInfo.id, group)
                }
                deviceGroup.value = group
                LiveEventBus.get("DeviceGroup_unbind", DeviceInfo::class.java).post(deviceInfo)
            }
            return true
        }
        return false
    }

    fun unbindAll() {
        val group = deviceGroup.value ?: return
        if (group.deviceList().isEmpty()) return
        launch {
            updateDialogLoading(true)
            withContext(Dispatchers.Default) {
                DeviceDatabase.get().unbindGroup(group.id)
            }
            updateDialogLoading(false)
            group.clear()
            deviceGroup.value = group
            clearEvent.setValue(true)
            LiveEventBus.get("DeviceGroup_unbindAll", DeviceGroup::class.java).post(group)
        }
    }

    //修改序号
    fun modifyNumber(number: Int, deviceInfo: DeviceInfo): Boolean {
        val group = deviceGroup.value ?: return false
        if (group.modifyDeviceInfoNumber(deviceInfo, number)) {
            launch {
                withContext(Dispatchers.Default) {
                    DeviceDatabase.get().modifyDeviceInfoNumber(group, deviceInfo)
                }
            }
            return true
        }
        return false
    }

    override fun onConnected(device: UBCDevice, isAssist: Boolean) {
        if (isAssist) return
        val group = deviceGroup.value ?: return
        val deviceInfo = group.findDeviceInfo(device.mac) ?: return
        deviceInfo.changeLine(true)
    }

    override fun onDisconnected(device: UBCDevice, isAssist: Boolean) {
        if (isAssist) return
        val group = deviceGroup.value ?: return
        val deviceInfo = group.findDeviceInfo(device.mac) ?: return
        deviceInfo.changeLine(false)
    }

    override fun onReadHex(device: UBCDevice, bytes: ByteArray, start: Int, size: Int, isAssist: Boolean) {
        if (isAssist) return
        val group = deviceGroup.value ?: return
        val deviceInfo = group.findDeviceInfo(device.mac) ?: return
        if (bytes.getOrNull(start) == HEADER &&
            bytes[start + 1].toUByte().toInt().shl(8) + bytes[start + 2] == DATA) {
            val battery = bytes[start + 3].toUByte().toInt()
            deviceInfo.modifyBattery(battery)
        }
    }

    override fun onRead(device: UBCDevice, data: String, isAssist: Boolean) {
    }
}